package br.com.equus.DAO.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import br.com.arquitetura.DAO.UniversalDAO;
import br.com.equus.DAO.AnimalDAO;
import br.com.equus.dto.PesquisarAnimalDTO;
import br.com.equus.entidade.Animal;
import br.com.equus.entidade.Proprietario;

@Repository(value = "animalDAO")
public class AnimalDAOImpl extends HibernateDaoSupport implements AnimalDAO {

	@Autowired(required = true)
	@Qualifier(value = "universalDAO")
	protected UniversalDAO dao;

	@Autowired(required = true)
	public void setFactory(SessionFactory factory) {
		super.setSessionFactory(factory);
	}

	@Override
	public Long countAnimal(PesquisarAnimalDTO dto) throws Exception {
		Criteria c = retornarCriteria(dto);
		c.setProjection(Projections.rowCount());

		Long result = (Long) c.list().get(0);
		return result;
	}

	@Override
	public List<Animal> paginateAnimal(int first, int pageSize, PesquisarAnimalDTO dto) throws Exception {
		Criteria c = retornarCriteria(dto);

		if (first != 0)
			c.setFirstResult(first);
		if (pageSize != 0)
			c.setMaxResults(pageSize);

		return c.list();
	}

	public Criteria retornarCriteria(PesquisarAnimalDTO dto) {
		if (dto == null) {
			return null;
		}

		Criteria criteria = getSession().createCriteria(Animal.class);

		if (dto.getCodigo() != null && !dto.getCodigo().isEmpty()) {
			criteria.add(Restrictions.eq("codigo", dto.getCodigo()));
		}

		if (dto.getNome() != null && !dto.getNome().isEmpty()) {
			criteria.add(Restrictions.ilike("nome", dto.getNome(), MatchMode.ANYWHERE));
		}
		if (dto.getIdade() != null && !dto.getIdade().isEmpty()) {
			criteria.add(Restrictions.eq("idade", Integer.valueOf(dto.getIdade())));
		}
		if (dto.getSexo() != null && !dto.getSexo().isEmpty()) {
			criteria.add(Restrictions.eq("sexo", dto.getSexo()));
		}
		if (dto.getProprietario() != null && dto.getProprietario().getId() != null) {
			criteria.createAlias("proprietario", "p");
			criteria.add(Restrictions.eq("p.id", dto.getProprietario().getId()));
		}
		if (dto.getProprietarioCriador() != null && dto.getProprietarioCriador().getId() != null) {
			criteria.createAlias("proprietarioCriador", "pc");
			criteria.add(Restrictions.eq("pc.id", dto.getProprietarioCriador().getId()));
		}
		if (dto.getIdRaca() != null && !dto.getIdRaca().equals(0)) {
			criteria.add(Restrictions.eq("raca.id", dto.getIdRaca()));
		}
		if (dto.getIdTipoAnimal() != null && !dto.getIdTipoAnimal().equals(0)) {
			criteria.add(Restrictions.eq("tipoAnimal.id", dto.getIdTipoAnimal()));
		}
		if (dto.getDtInicio() != null && dto.getDtFim() != null) {
			criteria.add(Restrictions.between("dtEntrada", dto.getDtInicio(), dto.getDtFim()));
		} else if (dto.getDtInicio() != null && dto.getDtFim() == null) {
			criteria.add(Restrictions.ge("dtEntrada", dto.getDtInicio()));
		} else if (dto.getDtInicio() == null && dto.getDtFim() != null) {
			criteria.add(Restrictions.le("dtEntrada", dto.getDtFim()));
		}

		return criteria;
	}

	@Override
	public List<Proprietario> carregaProprietario(String query)
			throws Exception {
		List<Proprietario> lista = null;
		lista = getSession().createQuery("from Proprietario p where upper(p.nome) like'%"+query.toUpperCase()+"%'" ).list();
		return lista;
	}
}
